/*****************************************************************************
 * file  : systask.c
 * creat : apleilx
 * data  : 2017/11/05
 *******************************************************************************/
#define _SYSTASK_MODULE_
#include "os_obj.h"
#include "sys_task.h"
#include "pincfg.h"
#include "framework.h"
#include "swap.h"
#include "nor_cmd.h"
#include "nand_w25n.h"
#include "bsp_api.h"
#include "mbedtls\aes.h"
#include "../coremark/coremark.h"
#include "bsp_swspi_nor.h"
#include "bsp_nand_w25n.h"
#include "bsp_qpi_nor.h"
#include "par\par_tab.h"
#include "symbol_def.h"
#include "par\prog.h"
#include "mem_alloc.h"
#include "bsp_io++.h"

using namespace std;

/*****************************************************************************
 * @brief   fun.
 *****************************************************************************/

void sw_iic_opt(void);
void sys_flash_init(void);
void sys_led_ctr(void);
void nor_flash_demo(void);
void sys_tick_exe(void);
void system_info(void);
void str_demo(void);
void sys_par_load(void);

obj_app_order(sys_led_ctr);
obj_init_order4(sys_par_load);
obj_init_order1(bsp_Init);
obj_init_order3(sys_flash_init);
obj_init_order2(system_info);

/*****************************************************************************
 * @brief   var.
 *****************************************************************************/
 class pin_ndef_class led1(GPIOB, 3);
 class pin_ndef_class led2(GPIOB, 4);

/*****************************************************************************
 * @brief   system task.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void task_system(const void *argument)
{
	uint32_t tick;

	sys_app_init();

	app_timer_task_add(sys_tick_exe);
	blk_sram.malloc(100);

	while (1)
	{
		sub2_add8(2, 200);

		fun_list_run_once(nsys);
		fun_list_run_once(napp);

		Gst.info.stack_used = stack_used();

		Gst.u_tick = app_tick_get();

		gp_par_get(0, gp_par_pos(stri_temp));

		// 虚拟RTC
		pulse_creat(&Gst.pulse, Gst.u_tick);
		sc_pulse_creat(Gst.u_tick);
		if (Gst.pulse.pulse_1s)
		{
			TimeRun(&Gst.rtc_time);
		}

		sys_app_run_once();

		// io_flt(&Gst.bios.sd_cd, 40, sd_cd.in_st());
		pwm_period_set(par_val_get(par_pos(pwm_period)));
		pwm_duty_set(0, par_val_get(par_pos(pwm_duty)));

		tick = app_tick_get();
		// bsp_dly_ms(200);
		Gst.bsp_dly_verify = app_tick_get() - tick;

		NOP1();
		osDelay(ms_ticks(10));
		NOP1();
	}
}

/*****************************************************************************
 * @brief   coremark.
 *****************************************************************************/
void coremark_demo(void)
{
	MAIN_RETURN_TYPE
	core_main(int argc, char *argv[]);

	if (Gst.b_coremark)
	{
		Gst.b_coremark = 0;
		// core_main(0,0);
	}
}

/*****************************************************************************
 * @brief   led control.
 *****************************************************************************/
void sys_led_ctr(void)
{
	static word_tt st = {1};

	if (!Gst.pulse.pulse_10ms)
		return;

	// 位移
	if (Gst.pulse.pulse_100ms)
	{
		st.uval = bit16_roll_shift_left(st.uval, 4, 1);
	}

	// 输出
	led1.out(st.bits.b0);
	led2.out(st.bits.b1);
}

/*****************************************************************************
 * @brief   flash opt.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void sys_flash_init(void)
{
	uint32_t ticksr;

	uint8_t *buff = (uint8_t *)malloc(2100);
	uint8_t *pdes = (uint8_t *)malloc(2100);

	(void)ticksr;

	nor_spi_init();
	nor_init(&sw_spi_nor, 1);
	Gst.flash.buff[0] = nor_reg_get(1);
	Gst.flash.buff[1] = nor_reg_get(2);
	Gst.flash.buff[2] = nor_reg_get(3);
	dbg_u8_print("nor reg :", Gst.flash.buff, 3, 14);

#if 0
	// wait
	nor_wait_for_busy();
	nor_write_enable();
	nor_reg_set(1, 0x02, 0x02);

	// read ID
	nor_id_read(Gst.flash.nor_id);
	dbg_u8_print("nor  id :", Gst.flash.nor_id, 4, 10);

	// read status
	Gst.flash.nor_sr[0] = nor_reg_get(1);
	Gst.flash.nor_sr[1] = nor_reg_get(2);
	Gst.flash.nor_sr[2] = nor_reg_get(3);
	dbg_u8_print("B:nor  sr :", Gst.flash.nor_sr, 3, 10);

	nor_q_read(1024*1024*13, 128, buff);
	if(buff[0] == 0xFF)
	{
		loop(1024)
			buff[index] = index;
		nor_q_write_multi(1024*1024*13, 1024, buff);
	}
	set_u32(buff, 0, 512);
	nor_q_read(1024*1024*13, 1024, buff);
	dbg_u8_print("nor dat @ 32 :\n", buff, 1024, 32);
#endif

	// Read Unique ID: 4Bh Dummy Dummy Dummy Dummy (UID63-0)
	bsp_snor_cmd_auto_get(0x4B, Gst.flash.buff, 12);
	dbg_u8_print("snor uuid :", Gst.flash.buff, 12, 14);

	// 设置寄存器
	bsp_snor_reg_set(3, 0x60, 0x00); // 设置驱动等级 REG3[6:5]
	bsp_snor_reg_set(2, 0x02, 0x02); // 开启QPI模式  REG2[2]
	Gst.flash.buff[0] = bsp_snor_reg_get(1);
	Gst.flash.buff[1] = bsp_snor_reg_get(2);
	Gst.flash.buff[2] = bsp_snor_reg_get(3);
	dbg_u8_print("snor reg :", Gst.flash.buff, 3, 14);

#if 0		
	dbg_u8_print("nor uuid :", Gst.flash.buff, 12, 14);
	Gst.flash.nor_sr[0] = bsp_snor_reg_get(1);
	Gst.flash.nor_sr[1] = bsp_snor_reg_get(2);
	Gst.flash.nor_sr[2] = bsp_snor_reg_get(3);
	dbg_u8_print("B:nor  sr:", Gst.flash.nor_sr, 3, 10);

	bsp_snor_read(1024*1024*12, 128, buff);
	if(buff[0] == 0xFF)
	{
		loop(1024)
			buff[index] = index;
		bsp_snor_write_multi(1024*1024*12, 1024, buff);
	}
	set_u32(buff, 0, 512);
	bsp_snor_read(1024*1024*12, 1024, buff);
	dbg_u8_print("nor dat @ 32 :\n", buff, 1024, 32);
#endif

	// uuid
	// Gst.flash.buff[0] = 0x4B;
	// loop(4) Gst.flash.buff[1+index] = 0xff;
	// bsp_snand_cmd_auto_get(0x4B, Gst.flash.buff, 12);
	// dbg_u8_print("NOR UUID: ", &Gst.flash.buff[4], 8, 10);

	// nand init
	bsp_snand_reset();
	bsp_snand_wait_ready();
	// bsp_w25n_init();
	// nand info config
	bsp_snand_info.block_total = 1024;
	bsp_snand_info.page_main_size = 2048;
	bsp_snand_info.page_spare_size = 16;
	bsp_snand_info.page_per_block = 64;

	bsp_snand_read_id(Gst.flash.nand_id);
	dbg_u8_print("nand id :", Gst.flash.nand_id, 4, 10);

	// default: 7C 18 00
	Gst.flash.nand_sr[0] = bsp_snand_featute_get(NAND_FEATURE_1_PROTECT);
	Gst.flash.nand_sr[1] = bsp_snand_featute_get(NAND_FEATURE_2_CFG);
	Gst.flash.nand_sr[2] = bsp_snand_featute_get(NAND_FEATURE_3_ST);
	dbg_u8_print("nand sr :", Gst.flash.nand_sr, 3, 10);

	// 去除写保护
	bsp_snand_featute_set(NAND_FEATURE_1_PROTECT, 0xFF, 0x00);

#if 0
	bsp_snand_block_erase(0);

	loop(128)
		Gst.flash.buff[index] = index + 1;
	bsp_snand_q_write_cache(0, Gst.flash.buff, 128);
	bsp_snand_program_exe(6);

	loop(128)
		Gst.flash.buff[index] = index + 3;
	bsp_snand_write_cache(0, Gst.flash.buff, 128);
	bsp_snand_program_exe(8);
#endif

#if 0	
	// 页读
	bsp_snand_read_page(6);
	bsp_snand_q_read_cache(0, Gst.flash.buff, 128);
	dbg_u8_print("nand page 6:\n", Gst.flash.buff, 128, 32);

	bsp_snand_read_page(8);
	bsp_snand_q_read_cache(0, Gst.flash.buff, 128);
	dbg_u8_print("nand page 8:\n", Gst.flash.buff, 128, 32);
	NOP1();
#endif

#if 0
	// 读取速度测试
	ticksr = app_tick_get();
	loop(1024 * 16)
	{
		bsp_snand_read_page(8);
		bsp_snand_q_read_cache(0, buff, 2048);
	}
	dbg_print("read size : %d MB, time : %d ms\n", 2 * 16, app_tick_get() - ticksr);
#endif
	free(buff);
	free(pdes);
}

/*****************************************************************************
 * @brief   str_demo
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void str_demo(void)
{
	int32_t site;
	e_copy_type cfg;

	uint8_t *buff = (uint8_t *)malloc(2100);
	uint8_t *pdes = (uint8_t *)malloc(2100);

	loop(1024)
		buff[index] = index;

	site = search_3B(buff, 512, 0, 511, 0x454647);
	dbg_print("search 0x454647 = %d \n", site);
	site = poll_search_3B(buff, 16, 8, 7, 0x0F0001);
	dbg_print("search 0x800001 = %d \n", site);
	site = poll_search_4B(buff, 16, 8, 7, 0x0F000102);
	dbg_print("search 0x80000102 = %d \n", site);

	cfg.des_len = 0x40;
	cfg.src_len = 0x20;
	cfg.start = 0x10;
	cfg.end = 0x0F;
	cfg.edat = 0x1F000102;

	ecopy(&cfg, buff, pdes, 1);
	dbg_print("copy e 1B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);
	ecopy(&cfg, buff, pdes, 2);
	dbg_print("copy e 2B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);
	ecopy(&cfg, buff, pdes, 3);
	dbg_print("copy e 3B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);
	ecopy(&cfg, buff, pdes, 4);
	dbg_print("copy e 4B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);

	cfg.des_len = 0x8;
	ecopy(&cfg, buff, pdes, 1);
	dbg_print("copy e 1B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);
	ecopy(&cfg, buff, pdes, 2);
	dbg_print("copy e 2B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);
	ecopy(&cfg, buff, pdes, 3);
	dbg_print("copy e 3B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);
	ecopy(&cfg, buff, pdes, 4);
	dbg_print("copy e 4B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);

	cfg.des_len = 0x40;
	cfg.edat = 0x0E0F1011;

	ecopy(&cfg, buff, pdes, 1);
	dbg_print("copy e 1B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);
	ecopy(&cfg, buff, pdes, 2);
	dbg_print("copy e 2B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);
	ecopy(&cfg, buff, pdes, 3);
	dbg_print("copy e 3B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);
	ecopy(&cfg, buff, pdes, 4);
	dbg_print("copy e 4B : site =%d, len = %d \n", cfg.res_site, cfg.res_len);
	dbg_u8_print("res : ", pdes, 32, 40);

	cfg.des_len = 0x40;
	cfg.edat = 0x1C1D1E1F;
	ecopy(&cfg, buff, pdes, 4);
	dbg_print("copy e 4B : site =%d, len = %d, next =%d \n", cfg.res_site, cfg.res_len, cfg.res_next);
	dbg_u8_print("res : ", pdes, 32, 40);

	cfg.des_len = 0x40;
	cfg.edat = 0x04050607;
	ecopy(&cfg, buff, pdes, 4);
	dbg_print("copy e 4B : site =%d, len = %d, next =%d \n", cfg.res_site, cfg.res_len, cfg.res_next);
	dbg_u8_print("res : ", pdes, 32, 40);

	free(buff);
	free(pdes);
}

/*****************************************************************************
 * @brief   iic opt.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
DBG_FUN_EXPORT(sw_iic_opt);
int sw_iic_opt(int argc, char **argv)
{
	uint8_t buff[64];

	sw_iic_init(sw_iic);
	at24_hal_link(&at24_obj);

	loop(64)
		buff[index] = index+32;

	at24_write(0, 64, buff);

	loop(64)
		buff[index] = 0;

	at24_read(0, 64, buff);

	dbg_u8_print("at data\n", buff, 64, 16);

	return 0;
}

/*****************************************************************************
 *
 * @brief   task switch hook.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void task_sw_hook(char pos)
{
}

/*****************************************************************************
 *
 * @brief   sys_par_load
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void sys_par_load(void)
{
	sys_par_flash_read();
	if (sys_par.ver_id.uval != VERSION_ID)
	{
		par_tab_init();
		sys_par_flash_save();
	}
}

/*****************************************************************************
 *
 * @brief   sys_tick_exe
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void sys_tick_exe(void)
{
}

/*****************************************************************************
 * @brief   system info.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void system_info(void)
{
	crm_clocks_freq_type clocks;

	crm_clocks_freq_get(&clocks);

	dbg_puts(SYMBOL_LINE_EQ CR);

	dbg_puts(asc_pic_light);

	dbg_puts(SYMBOL_LINE_EQ CR);
	dbg_print("HCLK = %d MHZ, PCLK1 = %d MHZ, PCLK2 = %d MHZ\n",
			  clocks.ahb_freq / 1000000,
			  clocks.apb1_freq / 1000000,
			  clocks.apb2_freq / 1000000);
	dbg_puts(SYMBOL_LINE_EQ CR);

	dbg_print("POS TEST : %d \n",
			  prog_par_pos(5, temp));
}

/*****************************************************************************
 * @brief   tick get.
 *
 * @ Pass/ Fail criteria: tick
 *****************************************************************************/
unsigned long rt_tick_get(void)
{
	return app_tick_get();
}

fun_list_hook(nsys)
{
}

/*****************************************************************************
 *
 * @brief   memdemo
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void mem_demo(void)
{
	uu16 *p[10];

	dbg_puts(SYMBOL_LINE_EQ CR);
	dbg_puts("malloc demo\n");
	dbg_puts(SYMBOL_LINE_EQ CR);

	p[1] = (uu16 *)malloc(100);
	loop(50)
		p[1][index] = index << 1;

	p[0] = (uu16 *)malloc(100);
	loop(50)
		p[0][index] = index;

	p[0] = (uu16 *)realloc(p[0], 110);
	p[0] = (uu16 *)realloc(p[0], 63);
	p[0] = (uu16 *)realloc(p[0], 120);
	p[0] = (uu16 *)realloc(p[0], 160);
	p[0] = (uu16 *)realloc(p[0], 63);
	p[0] = (uu16 *)realloc(p[0], 512);
	p[0] = (uu16 *)realloc(p[0], 1020);

	dbg_u16_print("U:P0:\n", p[0], 50, 10);
	dbg_u16_print("U:P1:\n", p[1], 50, 10);

	dbg_puts(SYMBOL_LINE_EQ CR);
}
// obj_init_order5(mem_demo);
